import QtQuick 1.1
import com.nokia.meego 1.0
import QuickGestures 1.0

Page {
    property bool finalRecognition: false
    property int recognizedId: -1
    property bool engineHasProvidedResult: false

    BusyLabel {
        id: busyLabel
        running: false
        text: "Recognizing..."
        height: 0
        opacity: 0
        z: 2
    }

    GestureVisualizer {
        id: sketchVisualizer
        anchors.fill: parent
        autoScale: false

        Component.onCompleted: {
            sketchGesture.clear();
            setGesture(sketchGesture);
        }
    }

    MouseArea {
        id: recognitionPageMouseArea

        property bool sketching: false
        property int numOfNewPoints: 0

        /**
         * @return True if the recognition was cancelled or already cancelling,
         *         false otherwise.
         */
        function cancelRecognition()
        {
            if (engine.state != 0) {
                if (engine.state == 1 || engine.state == 2) {
                    engine.cancelRecognition();
                }
                else {
                    console.debug("STILL CANCELLING...");
                }

                return true;
            }

            return false;
        }

        /**
         *
         */
        function handleChanges()
        {
            if (numOfNewPoints < 20) {
                return;
            }

            if (cancelRecognition()) {
                return;
            }

            numOfNewPoints = 0;

            // Hide the recognition visualizer if visible.
            if (recognitionVisualizer.opacity > 0) {
                recognitionVisualizer.opacity = 0;
            }

            // Start recognition process.
            engine.recognize(sketchGesture);
        }

        anchors.fill: parent
        z: 1

        onPressed: {
            console.debug("RecognitionView.qml: recognitionPageMouseArea::onMousePress");

            if (!recognitionPageMouseArea.sketching) {
                // Cancel recognition if ongoing.
                cancelRecognition();

                // Clear the recognition visualizer.
                if (hideTimer.running) {
                    hideTimer.stop();
                }

                if (recognitionVisualizer.opacity > 0) {
                    recognitionVisualizer.opacity = 0;
                }

                // Reset values.
                engineHasProvidedResult = false;
                finalRecognition = false;
                recognizedId = -1;
                numOfNewPoints = 0;

                // Clear the previous gesture.
                sketchGesture.clear();
                recognitionPageMouseArea.sketching = true;
            }
            else {
                // Stop the timer and add a break point.
                stopTimer.stop();
                sketchGesture.appendPoint(-1, -1);
            }

            sketchGesture.appendPoint(mouse.x, mouse.y);
            numOfNewPoints += 1;
            handleChanges();
        }
        onMousePositionChanged: {
            if (recognitionPageMouseArea.sketching) {
                sketchGesture.appendPoint(mouse.x, mouse.y);
                numOfNewPoints += 1;
                handleChanges();
            }
        }
        onReleased: {
            stopTimer.restart();
        }
    }

    Timer {
        id: stopTimer
        running: false
        repeat: false
        interval: 1000

        onTriggered: {
            console.debug("RecognitionView.qml: stopTimer::onTriggered");
            recognitionPageMouseArea.sketching = false;

            if (recognitionPageMouseArea.numOfNewPoints > 15 || !engineHasProvidedResult) {
                engine.recognize(sketchGesture);
                recognitionPageMouseArea.numOfNewPoints = 0;
            }
            else {
                console.debug("RecognitionView.qml: stopTimer::onTriggered:",
                              "Not enough new points to trigger recognition.");
                recognitionVisualizer.opacity = 0.8;
            }

            finalRecognition = true;
        }
    }

    // A visualizer for displaying the recognized gesture.
    GestureVisualizer {
        id: recognitionVisualizer

        /**
         * Calculates the position and the size for this item before showing
         * the visualizer.
         */
        function show()
        {
            console.debug("RecognitionView.qml: GestureVisualizer::show()");
            hideTimer.restart();

            if (finalRecognition && recognitionVisualizer.opacity < 0.8) {
                recognitionVisualizer.opacity = 0.8;
            }
            else if (recognitionVisualizer.opacity < 0.1) {
                recognitionVisualizer.opacity = 0.1;
            }

            var absX = (parent.width - width) / 2;
            var absY = (parent.height - height) / 2;

            if (recognitionVisualizer.gesture) {
                x = absX + (width - contentWidth) / 2;
                y = absY + (height - contentHeight) / 2;
            }
            else {
                x = absX;
                y = absY;
            }

            //console.debug("[", x, ",", y, "]");
        }

        x: (parent.width - width) / 2
        y: (parent.height - height) / 2
        width: parent.width * 4 / 5
        height: parent.height * 4 / 5
        opacity: 0
        z: 2
        lineWidth: 12
        lineColor: "lightgreen"

        Behavior on opacity {
            NumberAnimation { duration: 600 }
        }

        Component.onCompleted: {
            x = (parent.width - width) / 2;
            y = (parent.height - height) / 2;
        }
    }

    Connections {
        target: engine

        onSucceeded: {
            console.debug("Recognized gesture with ID", id);
            recognizedId = id;
            engineHasProvidedResult = true;
            recognitionVisualizer.setGesture(gestureModel.gestureById(id));
            recognitionVisualizer.show();
        }

        onFailed: {
            console.debug("Failed to recognize the gesture!");
            recognizedId = -1;
            engineHasProvidedResult = true;
            recognitionVisualizer.setGesture(0);
            recognitionVisualizer.show();
        }

        onStateChanged: {
            if (state == QuickGesturesEngine.Idle
                    || state == QuickGesturesEngine.Cancelling) {
                console.debug("RecognitionView.qml: Engine idle or cancelling.");
                busyLabel.hide();
            }
            else if (state == QuickGesturesEngine.Processing
                     || state == QuickGesturesEngine.Recognizing) {
                console.debug("RecognitionView.qml: Engine processing or recognizing.");
                busyLabel.show();
            }
        }
    }

    Timer {
        id: hideTimer
        running: false
        repeat: false
        interval: 10000

        onTriggered: {
            recognitionVisualizer.opacity = 0;
        }
    }

    // Tool bar
    tools: ToolBarLayout {
        ToolIcon {
            iconId: "toolbar-back"
            onClicked: pageStack.pop();
        }
    }
}

// End of file.
